package de.jmda.mproc.swingui;

import java.io.FileFilter;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import javax.swing.SwingWorker;

import de.jmda.util.RuntimeUtil;
import de.jmda.util.classpath.ClasspathResource;
import de.jmda.util.classpath.ClasspathUtil;

/**
 *
 */
public class AnnotationProcessorDictionary
		extends SwingWorker<List<String>, Void>
{
	/**
	 * filter for resource containers listed in <code>
	 * System.getProperty("java.class.path")</code>
	 */
	private FileFilter resourceContainerFilter =
			ClasspathUtil.NONE_REJECTING_FILE_FILTER;

	/**
	 * will be calculated and returned by {@link #doInBackground()}
	 */
	private List<String> abstractProcessorClassNames = new LinkedList<String>();

	/**
	 * constructor, starts calculation of {@link #abstractProcessorClassNames} in
	 * background
	 *
	 * @param resourceContainerFilter filter for container resources
	 */
	public AnnotationProcessorDictionary(FileFilter resourceContainerFilter)
	{
		super();
		this.resourceContainerFilter = resourceContainerFilter;
		// start calculation in background
		execute();
	}
	
	/**
	 * constructor, starts calculation of {@link #abstractProcessorClassNames} in
	 * background, uses {@link ClasspathUtil#NONE_REJECTING_FILE_FILTER} as
	 * filter for container resources
	 */
	public AnnotationProcessorDictionary()
	{
		super();
		execute();
	}
	
	public List<String> getAnnotationProcessorClassnames()
	{
		List<String> result = null;

		String errMsg = "failure getting annotation processor classnames";

		try
    {
	    result = get();
    }
    catch (InterruptedException e)
    {
    	throw new IllegalStateException(errMsg, e);
    }
    catch (ExecutionException e)
    {
    	throw new IllegalStateException(errMsg, e);
    }
		
    return result;
	}

	@Override
  protected List<String> doInBackground() throws Exception
  {
		LaunchableAnnotationProcessorFilter launchableAnnotationProcessorFilter =
				new LaunchableAnnotationProcessorFilter();
	
		List<ClasspathResource> classpathResources =
				ClasspathUtil.getClasspathResources(
						resourceContainerFilter,
						launchableAnnotationProcessorFilter,
						launchableAnnotationProcessorFilter);
		
		for (ClasspathResource classpathResource : classpathResources)
		{
			String resourcename = classpathResource.getResourcename();
			abstractProcessorClassNames.add(
					resourcename.substring(0, resourcename.lastIndexOf('.')) // rtrim .class
					            .replace(RuntimeUtil.FILE_SEPARATOR, "."));
		}
	
		return abstractProcessorClassNames;
  }
}